
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>模板方法模式与钩子方法配合使用 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>模板方法模式与钩子方法配合使用 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是模板方法模式的核心思想？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">模板方法模式的核心思想是在一个基类中定义算法的固定框架或骨架，同时允许子类覆盖或实现算法中的某些特定步骤，即将部分步骤的实现延迟到子类中完成。</div>
          </div>
          <div class="card-source">来源: 1. 模板方法模式的核心思想</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在模板方法模式中，钩子方法（Hook Method）扮演着什么角色？它与抽象方法有何不同？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">钩子方法是模板方法模式中的一个关键点，它在基类中提供一个默认实现，子类可以选择性地重写它来扩展或修改算法行为。它与抽象方法不同，抽象方法没有实现，必须由子类强制实现，而钩子方法是可选的。</div>
          </div>
          <div class="card-source">来源: 模板方法模式与钩子方法的配合使用 & 1. 模板方法模式的核心思想</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">钩子方法主要通过哪些方式来增强模板方法的灵活性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">钩子方法主要通过三种方式增强灵活性：1. 决定某些步骤是否执行（例如返回布尔值）；2. 调整默认行为（通过覆写方法）；3. 在固定步骤中插入额外的定制逻辑。</div>
          </div>
          <div class="card-source">来源: 2. 钩子方法的作用</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在“饮料制作过程”的示例中，`Tea`子类是如何利用钩子方法`customerWantsCondiments()`来改变行为的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在`Beverage`基类中，`customerWantsCondiments()`钩子方法默认返回`true`。`Tea`子类通过重写该方法并返回`false`，使得模板方法`prepareRecipe()`在执行时跳过了`addCondiments()`这一步骤，从而实现了定制化的流程。</div>
          </div>
          <div class="card-source">来源: 3. 模板方法模式与钩子方法配合的典型实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">模板方法模式如何体现了“开闭原则”？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">模板方法模式通过将算法的整体结构固定在父类中（对修改关闭），同时允许子类通过实现抽象方法或重写钩子方法来扩展具体行为（对扩展开放），从而遵循了开闭原则。</div>
          </div>
          <div class="card-source">来源: 4. 模板方法模式与钩子方法的优点</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">模板方法模式与钩子方法的结合在哪些实际场景中有广泛应用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">这种模式组合广泛应用于：1. 框架与工具类开发（如Spring的`BeanPostProcessor`）；2. 工作流或任务处理系统，允许开发者定制任务逻辑；3. 算法扩展，如机器学习中提供固定预处理流程并允许自定义扩展。</div>
          </div>
          <div class="card-source">来源: 5. 应用场景</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">在模板方法模式中，各个关键组成部分（模板方法、抽象方法、钩子方法）分别承担什么职责？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. 模板方法：在父类中定义，规定算法的步骤和顺序，通常不可修改。 2. 抽象方法：定义算法中必须由子类实现的步骤。 3. 钩子方法：提供默认实现，子类可选择性重写以决定是否扩展或修改算法行为。</div>
          </div>
          <div class="card-source">来源: 1. 模板方法模式的核心思想</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">在使用模板方法模式和钩子方法时，有哪些需要注意的事项以避免潜在问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">需要注意三点：1. 避免钩子方法的滥用，过多的钩子会使子类实现混乱；2. 保持模板方法的流程清晰，避免过于复杂；3. 为钩子方法提供合理的默认行为，避免子类必须实现所有钩子。</div>
          </div>
          <div class="card-source">来源: 6. 可能的优化与注意事项</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在“饮料制作过程”示例中，为什么`prepareRecipe()`方法被声明为`final`？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`prepareRecipe()`方法是定义算法骨架的模板方法。将其声明为`final`是为了防止子类重写该方法，从而确保算法的整体结构和步骤顺序是固定不变的，这正是模板方法模式的核心目的。</div>
          </div>
          <div class="card-source">来源: 3. 模板方法模式与钩子方法配合的典型实现</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
